package com.asiainfo.dacp.datastash.broker.listener;

import org.springframework.scheduling.annotation.Async;

import com.asiainfo.dacp.core.BeanFactory;
import com.asiainfo.dacp.datastash.broker.core.BrokerException;
import com.asiainfo.dacp.datastash.broker.core.vo.StashUnit;
import com.asiainfo.dacp.datastash.broker.facade.UnitDependFacade;
import com.asiainfo.dacp.datastash.broker.facade.UnitProcessFacade;
import com.asiainfo.dacp.datastash.broker.facade.state.UnitStateLogService;
import com.asiainfo.dacp.datastash.broker.tracelog.StashTraceLogVo;
import com.asiainfo.dacp.datastash.broker.tracelog.StashTraceLogger;

/**
 * 监听等待判断依赖的队列（unit_wait_queue）
 *
 * 发现有任务存在就去判断依赖（争抢机制），不循环只执行一次判断，判断失败重新排队
 *
 * @author MeiKefu
 * @date 2017-11-21
 */
public class UnitWaitQueueListener extends AbstractQueueListener {

    private String clzName = this.getClass().getSimpleName();

    /**
     * unit任务处理
     */
    @Async
    protected void handle(){
        StashTraceLogger tracelog = BeanFactory.getBean(StashTraceLogger.class);
        UnitDependFacade unitDependFacade = BeanFactory.getBean(UnitDependFacade.class);

        UnitStateLogService stateChangeService = BeanFactory.getBean(UnitStateLogService.class);
        
        //增加依赖判断总数／频次，且更新state表
        
        StashUnit stashUnit = unitDependFacade.fetchWaitingStashUnit();
        if(stashUnit!=null){
            tracelog.info(StashTraceLogVo.buildStashTraceLogVo(stashUnit,clzName,"waitQueueLis:fetch","获取Wait队列中单元"));

             //TODO  这里应该设置个重新入队/依赖判断间隔,应该由每个任务自己指定，目前先写死
            if(!unitDependFacade.arrivalJuding(stashUnit)){
            	
                tracelog.info(StashTraceLogVo.buildStashTraceLogVo(stashUnit,clzName,"waitQueueLis:noArrival","依赖到达未触发，重新入队"));
                
                try {
					Thread.sleep(100);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
                unitDependFacade.requeue(stashUnit);
            }else{
                tracelog.info(StashTraceLogVo.buildStashTraceLogVo(stashUnit,clzName,"waitQueueLis:arrived","依赖到达成功"));
                
                //TODO 目前暂时不考虑资源阻塞 
                try{
                	stateChangeService.runnable(stashUnit);
                	UnitProcessFacade unitProcessFacade = BeanFactory.getBean(UnitProcessFacade.class);
                    unitProcessFacade.processUnit(stashUnit);
                    
                }catch(BrokerException exception){
                    tracelog.error(StashTraceLogVo.buildStashTraceLogVo(stashUnit,clzName,"error::",exception.getMessage()));
                } 
                
            }
        }else{
            tracelog.debug(new StashTraceLogVo(clzName,"waitQueueLis:fetch:none","未获取到Wait队列中单元"));
        }
    }

}
